package edu.pku.sei.transformation.editor.model.test;

import java.util.ArrayList;
import java.util.List;

import org.w3c.dom.Element;

import edu.pku.sei.modeler.model.xml.XMLUtility;
import edu.pku.sei.transformation.editor.model.ModelPackage;
import edu.pku.sei.transformation.editor.model.base.NamedElement;
import edu.pku.sei.transformation.editor.model.constraint.ConstraintConnection;
import edu.pku.sei.transformation.editor.model.constraint.IConstrainableElement;

public class CheckPoint extends NamedElement implements IConstrainableElement {
	private int state = STATE_NONE;
	public static final int STATE_SUCCEED = 1;
	public static final int STATE_FAIL = -1;
	public static final int STATE_NONE = 0;

	// public static final int TYPE_ASSERT_TRUE = 0X0;
	// public static final int TYPE_ASSERT_FALSE = 0X1;
	// public static final int TYPE_ASSERT_NULL = 0X2;
	// public static final int TYPE_ASSERT_NOT_NULL = 0X3;
	// public static final int TYPE_ASSERT_EQUAL = 4;
	// public static final int TYPE_ASSERT_NOT_EQUAL = 5;
	// protected int type;
	// private static final String[] typeStrings = new
	// String[]{"Assert True","Assert False","Assert Null","Assert Not Null",
	// "Assert Equal","Assert Not Equal"};
	private ArrayList<ConstraintConnection> constraintConnections = new ArrayList<ConstraintConnection>();
	protected ArrayList<CheckPointOperand> operands = new ArrayList<CheckPointOperand>();

	public boolean canAddOperand() {
		// switch(type) {
		// case TYPE_ASSERT_TRUE:
		// case TYPE_ASSERT_FALSE:
		// case TYPE_ASSERT_NULL:
		// case TYPE_ASSERT_NOT_NULL:
		// return operands.size() == 0;
		// case TYPE_ASSERT_EQUAL:
		// case TYPE_ASSERT_NOT_EQUAL:
		// return operands.size() < 2;
		// default:
		// return false;
		// }
		return true;
	}

	public boolean addOperand(CheckPointOperand operand) {
		if (canAddOperand())
			return operands.add(operand);
		else
			return false;
	}

	public boolean removeOperand(CheckPointOperand operand) {
		return operands.remove(operand);
	}
	
	public ArrayList<CheckPointOperand> getOperands() {
		return operands;
	}

	// public int getType() {
	// return type;
	// }
	//	
	// public void setType(int newValue) {
	// if (this.type != newValue) {
	// int oldValue = this.type;
	// this.type = newValue;
	// firePropertyChange(ModelPackage.CHECK_POINT_TYPE, oldValue, newValue);
	// }
	// }

	// @MethodProperty(id = ModelPackage.CHECK_POINT_TYPE, catalog =
	// "Check Point", name = "type", setter = "setTypeString")
	// @EnumerationProperty(function = "getTypeStrings")
	// public String getTypeString() {
	// switch(type) {
	// case TYPE_ASSERT_TRUE:
	// return typeStrings[0];
	// case TYPE_ASSERT_FALSE:
	// return typeStrings[1];
	// case TYPE_ASSERT_NULL:
	// return typeStrings[2];
	// case TYPE_ASSERT_NOT_NULL:
	// return typeStrings[3];
	// case TYPE_ASSERT_EQUAL:
	// return typeStrings[4];
	// case TYPE_ASSERT_NOT_EQUAL:
	// return typeStrings[5];
	// default:
	// return typeStrings[0];
	// }
	// }

	// public void setTypeString(String s) {
	// if (typeStrings[0].equals(s)) {
	// setType(TYPE_ASSERT_TRUE);
	// } else if (typeStrings[1].equals(s)) {
	// setType(TYPE_ASSERT_FALSE);
	// } else if (typeStrings[2].equals(s)) {
	// setType(TYPE_ASSERT_NULL);
	// } else if (typeStrings[3].equals(s)) {
	// setType(TYPE_ASSERT_NOT_NULL);
	// } else if (typeStrings[4].equals(s)) {
	// setType(TYPE_ASSERT_EQUAL);
	// } else if (typeStrings[5].equals(s)) {
	// setType(TYPE_ASSERT_NOT_EQUAL);
	// }
	// }

	// public Object[] getTypeStrings() {
	// return typeStrings;
	// }
	public int getState() {
		return state;
	}

	public void setState(int state) {
		this.state = state;
	}

	@Override
	public void serialize(Element root) {
		super.serialize(root);
		XMLUtility.xmlInstance.serializeAttribute(root,
				ModelPackage.CHECK_POINT_STATE, state);
		// XMLUtility.xmlInstance.serializeAttribute(root,
		// ModelPackage.CHECK_POINT_TYPE, type);
		XMLUtility.xmlInstance.serializeNodes(root,
				ModelPackage.CHECK_POINT_OPERANDS, operands);
		XMLUtility.xmlInstance.serializeNodes(root,
				ModelPackage.CHECK_POINT_CONSTRAINT, constraintConnections);
	}

	@Override
	public void deSerialize(Element root) {
		super.deSerialize(root);
		state = XMLUtility.xmlInstance.deSerializeInt(root,
				ModelPackage.CHECK_POINT_STATE);
		// type = XMLUtility.xmlInstance.deSerializeInt(root,
		// ModelPackage.CHECK_POINT_TYPE);
		this.operands.addAll(XMLUtility.xmlInstance.deSerializeNodes(root,
				ModelPackage.CHECK_POINT_OPERANDS));
		this.constraintConnections.addAll(XMLUtility.xmlInstance
				.deSerializeNodes(root, ModelPackage.CHECK_POINT_CONSTRAINT));
	}

	@Override
	public String toString() {
		if (getName() == null && getName().equals(""))
			return "unnamed checkpoint";
		else
			return getName();
	}

	@Override
	public List<ConstraintConnection> getConstraintConnections() {
		return this.constraintConnections;
	}

}
